package com.yxy.utils;

import com.google.zxing.BarcodeFormat;
import com.google.zxing.EncodeHintType;
import com.google.zxing.MultiFormatWriter;
import com.google.zxing.client.j2se.MatrixToImageWriter;
import com.google.zxing.common.BitMatrix;
import lombok.extern.slf4j.Slf4j;

import java.io.DataInputStream;
import java.io.File;
import java.text.SimpleDateFormat;
import java.time.LocalDate;
import java.time.format.DateTimeFormatter;
import java.util.Date;
import java.util.HashMap;
import java.util.Map;

@Slf4j
public class QRCodeGenerator {

    private static final String SIGHTS_DIR = "qr/sights";
    private static final String HOTEL_DIR = "qr/hotel";
    public static final int SIGHTS = 1;
    public static final int HOTEL = 2;


    /**
     * 生成二维码
     *
     * @param text      二维码中要编码的文本
     * @param width     二维码图片的宽度（像素）
     * @param height    二维码图片的高度（像素）
     * @param bookingId 预约id
     * @param type      1：景点，2：酒店
     * @throws Exception
     */
    public static String generateQRCodeImage(String text, int width, int height, int bookingId, int type) throws Exception {
        // 用于存储二维码生成时的配置参数（提示信息）
        Map<EncodeHintType, Object> hintMap = new HashMap<>();
        // 添加一个配置项，指定二维码内容的字符集为utf-8
        hintMap.put(EncodeHintType.CHARACTER_SET, "UTF-8");

        // ZXing库中用于生成条形码或二维码的核心类
        MultiFormatWriter multiFormatWriter = new MultiFormatWriter();
        // 生成二维码矩阵，参数说明：二维码内容、二维码格式、宽度、高度、配置参数
        BitMatrix bitMatrix = multiFormatWriter.encode(text, BarcodeFormat.QR_CODE, width, height, hintMap);

        // 获取当前日期并格式化为字符串
        DateTimeFormatter formatter = DateTimeFormatter.ofPattern("yyyy-MM-dd");
        LocalDate currentDate = LocalDate.now();
        String currentDateString = currentDate.format(formatter);

        // 获取前一天的日期
        LocalDate previousDate = currentDate.minusDays(1);
        String previousDateString = previousDate.format(formatter);

        // 判断类型并生成文件路径
        String directory = (type == 1) ? SIGHTS_DIR : HOTEL_DIR;
        String fullDirectory = directory + File.separator + currentDateString;

        // 创建当天日期的文件夹（如果不存在）
        File currentDir = new File(fullDirectory);
        if (!currentDir.exists()) {
            currentDir.mkdirs(); // 创建多级目录
        }

        // 删除前一天的所有文件夹
        deletePreviousDirectories(directory, currentDateString);

        // 组装完整路径
        String filePath = fullDirectory + File.separator + bookingId + ".png";
        File file = new File(filePath);

        // 将二维码矩阵写入文件，参数说明：二维码矩阵、图片格式、图片路径
        MatrixToImageWriter.writeToPath(bitMatrix, "PNG", file.toPath());
        // 返回文件的绝对路径
        return file.getAbsolutePath();
    }

    /**
     * 删除指定目录前的所有文件夹
     * @param directory 根目录（hotel/sights)
     * @param baseDate 当前日期
     */
    private static void deletePreviousDirectories(String directory, String baseDate){
        File baseDir = new File(directory);
        if(!baseDir.exists() || !baseDir.isDirectory()){
            log.info("指定路径不存在后不是一个目录：{}", directory);
            return;
        }

        // 将基准日期转换为时间戳
        long baseTimestamp = covertDateToTimestamp(baseDate);
        if(baseTimestamp == -1){
            log.info("无效基准日期：{}", baseDate);
            return;
        }

        // 遍历目录下的所有子文件夹
        for (File subDir : baseDir.listFiles()) {
            if(subDir.isDirectory()){
                try{
                    // 提取文件夹名称并解析为时间戳
                    long subDirTimestamp = covertDateToTimestamp(subDir.getName());
                    if(subDirTimestamp != -1 && subDirTimestamp < baseTimestamp){
                        // 删除早于基准日期的文件夹及其文件
                        deleteDirectory(subDir);
                        log.info("已删除文件夹：{}", subDir.getAbsolutePath());
                    }
                } catch (Exception e) {
                    log.info("无法解析文件夹：{}", subDir.getName());
                }
            }
        }
    }

    /**
     * 辅助方法：递归删除文件夹
     * @param directory
     */
    private static void deleteDirectory(File directory) {
        if (directory.isDirectory()) {
            File[] files = directory.listFiles();
            if (files != null) {
                for (File file : files) {
                    if(file.isDirectory()){
                        deleteDirectory(file); // 递归删除子文件夹
                    }else{
                        file.delete(); // 删除文件
                    }
                }
            }
        }
        directory.delete(); // 删除空文件夹
    }

    /**
     * 将日期字符串转换为时间戳
     * @param dateStr
     * @return
     */
    private static long covertDateToTimestamp(String dateStr) {
        try{
            SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd");
            Date date = sdf.parse(dateStr);
            return date.getTime();
        }catch (Exception e){
            return -1;
        }
    }
}
